CanvasRenderingContext2D.prototype.drawPeriodicTable = function() {
  var scale = this.canvas.width / 18;
  for (var i = 1; i <= 118; i++) {
    var x, y;
    if (i <= 2) {
      x = i == 1 ? 0 : scale * 17;
      y = 0;
    } else  if (i <= 10) {
      x = (i + (i <= 4 ? -3 : 7)) * scale;
      y = scale;
    } else if (i <= 18) {
      x = (i + (i <= 12 ? -11 : -1)) * scale;
      y = 2 * scale;
    } else if (i <= 36) {
      x = (i - 19) * scale;
      y = 3 * scale;
    } else if (i <= 54) {
      x = (i - 37) * scale;
      y = 4 * scale;
    } else if (i <= 56 || (72 <= i && i <= 86)) {
      x = (i + (i <= 56 ? -55 : -69)) * scale;
      y = 5 * scale;
    } else if (57 <= i && i <= 71) {
      x = (i - 54) * scale;
      y = 8 * scale;
    } else if (i <= 88 || (104 <= i && i <= 118)) {
      x = (i + (i <= 88 ? -87 : -101))  * scale;
      y = 6 * scale;
    } else if (89 <= i && i <= 103) {
      x = (i - 86) * scale;
      y = 9 * scale;
    }
    y += 0.5 * scale;
    this.drawPeriodicSquare(getElementByAtomicNumber(i), x, y, scale);
  }
  this.textAlign = "center";
  this.textBaseline = "middle";
  this.fillStyle = "black";
  this.font = 0.32 * scale + "px serif";
  for (var j = 1; j <= 18; j++) {
    var y = (0.25 + (j != 1 && j != 18 ? 1 : 0) + (3 <= j && j <= 12 ? 2 : 0)) * scale;
    this.fillText(j, (j - 0.5) * scale, y, scale);
  }
  this.fillStyle = "rgb(192,255,255)";
  this.beginPath();
  this.moveTo(2 * scale, 5.5 * scale);
  this.lineTo(3 * scale, 5.5 * scale);
  this.lineTo(3 * scale, 8 * scale);
  this.lineTo(18 * scale, 8 * scale);
  this.lineTo(18 * scale, 8.5 * scale);
  this.lineTo(3 * scale, 8.5 * scale);
  this.lineTo(3 * scale, 10.5 * scale);
  this.lineTo(2 * scale, 10.5 * scale);
  this.fill();
};

CanvasRenderingContext2D.prototype.drawPeriodicSquare = function(e, x, y, scale) {
  this.lineWidth = 0.003 * scale;

  switch (e.group) {
    case 1 : this.fillStyle = "#E6A73A"; break;
    case 2 : this.fillStyle = "#95F144"; break;
    case 17 : this.fillStyle = "#F8FF52"; break;
    case 18 : this.fillStyle = "#BD97C6"; break;
    default : this.fillStyle = "#AAAAAA"; break;
  }
  this.strokeStyle = "#000000";
  this.fillRect(x, y, scale, scale);
  this.strokeRect(x, y, scale, scale);

  this.textAlign = "left";
  this.textBaseline = "top";
  this.fillStyle = "#000000";
  this.font = Math.floor(scale * 0.4) + "px serif";
  this.fillText(e.symbol, x + 0.1 * scale, y + 0.1 * scale, scale);

  this.font = Math.floor(scale * 0.16) + "px serif";
  this.fillText(e.name, x + 0.1 * scale, y + 0.55 * scale, scale);

  this.font = "small-caps " + Math.floor(scale * 0.16) + "px serif";
  this.fillText(e.mass, x + 0.1 * scale, y + 0.75 * scale, scale);

  this.font = "small-caps " + Math.floor(scale * 0.2) + "px serif";
  this.textAlign = "right";
  this.fillText(e.number, x + 0.95 * scale, y + 0.02 * scale, scale);
};

CanvasRenderingContext2D.prototype.drawPeriodicSquare2 = function(e, x, y, scale) {
  var split = String(e.mass).split(".");
  if (split[1].length > 2) {
    e.mass = split[0] + "." + split[1].substring(0,2);
  }
  this.drawPeriodicSquare(e, x, y, scale);
};